

#include <QFile>
#include <QByteArray>
#include "comm_utils.h"
#include "ev_cmd_type.h"
#include "task_firm_upgrade.h"

FirmwareUpgradeTask::FirmwareUpgradeTask(EvSerial *serial, const QString &filePath)
    : TaskCommBase(serial)
{
    m_filePath = filePath;
    setAutoDelete(true);
}

void FirmwareUpgradeTask::run()
{
    QString mssg = QString("升级固件 ...");
    emit messageLogged(LogUtils::makeLogBin(mssg));


    mssg = QString("-- 读取文件 ...");
    emit messageLogged(LogUtils::makeLogBin(mssg));
    QFile file(m_filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        mssg = QString("-- 读取文件失败: %1").arg(m_filePath);
        emit messageLogged(LogUtils::makeLogBin(mssg));
        emit finished(false);
        return;
    }
    QByteArray binaryData = file.readAll();
    file.close();
    uint32_t firm_len = binaryData.size();
    if ((firm_len % EV_CALL_OTA_DATA_LEN) != 0 || firm_len < EV_CALL_OTA_DATA_LEN) {
        mssg = QString("-- 固件长度错误: %1").arg(firm_len);
        emit messageLogged(LogUtils::makeLogBin(mssg));
        emit finished(false);
        return;
    }
    mssg = QString("-- 固件文件长度: %1").arg(firm_len);
    emit messageLogged(LogUtils::makeLogBin(mssg));


    mssg = QString("-- 擦除固件 ...");
    emit messageLogged(LogUtils::makeLogBin(mssg));
    int ret = callOtaStart(firm_len);
    if (ret) {
        mssg = QString("-- 擦除固件失败, 错误码: %1").arg(ret);
        emit messageLogged(LogUtils::makeLogBin(mssg));
        emit finished(false);
        return;
    }


    mssg = QString("-- 写入固件 ...");
    emit messageLogged(LogUtils::makeLogBin(mssg));
    uint32_t pkt_num = (firm_len - 1) / EV_CALL_OTA_DATA_LEN + 1;
    for (uint32_t i = 0; i < pkt_num; i++) {
        ret = callOtaData(i, (const uint8_t *)(binaryData.constData() + i * EV_CALL_OTA_DATA_LEN));
        if (ret) {
            mssg = QString("-- 固件写入失败, 错误码: %1").arg(ret);
            emit messageLogged(LogUtils::makeLogBin(mssg));
            emit finished(false);
            return;
        }
        emit progressUpdated(i * 100 / pkt_num);
    }


    mssg = QString("-- 校验固件 ...");
    emit messageLogged(LogUtils::makeLogBin(mssg));
    ret = callOtaEnd();
    if (ret) {
        mssg = QString("-- 校验固件失败, 错误码: %1").arg(ret);
        emit messageLogged(LogUtils::makeLogBin(mssg));
        emit finished(false);
        return;
    }
    emit messageLogged(LogUtils::makeLogBin("固件升级成功"));
    emit finished(true);
}



